Skip to content

[FEAT] OAuth callback 처리 상태 관리 - #140

Merged
ownue merged 2 commits into
developfrom
feat/#35-oauth-callback
Aug 12, 2026
Merged

[FEAT] OAuth callback 처리 상태 관리#140
ownue merged 2 commits into
developfrom
feat/#35-oauth-callback

Conversation

@ownue

@ownue ownue commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

📌 관련 이슈

✨ 작업 내용

  • OAuth 인증 요청에 ISSUED, PROCESSING, SUCCEEDED, FAILED 상태 추가
  • callback 요청 시 ISSUED → PROCESSING 원자적 상태 전환 구현
  • 동일 state를 사용한 중복·동시 callback 요청 방지
  • 토큰 교환 및 외부 계정 저장 완료 시 SUCCEEDED 처리
  • callback 검증, 토큰 교환, 사용자 정보 조회, DB 저장 실패 시 FAILED 처리
  • 실패 단계와 민감정보를 제외한 오류 분류 enum 저장
  • 15분 이상 유지되는 PROCESSING 요청 자동 실패 처리
  • 실패한 authorization code를 재사용하지 않고 신규 인가 요청으로 복구
  • 상태 전환, 부분 실패, 동시 요청 및 timeout 경쟁 조건 테스트 추가

📸 UI 작업 시

X

✅ 체크 리스트

  • develop 브랜치를 pull 완료했는가?
  • Merge 하려는 브랜치가 올바른가?
  • Merge 하려는 PR 및 Commit들을 로컬에서 실행했을 때 에러가 발생하지 않았는가?

Summary by CodeRabbit

  • 개선 사항

    • OAuth 콜백 처리 상태를 단계별로 관리해 중복 처리를 방지합니다.
    • 인증, 토큰 교환, 사용자 정보 조회, 계정 저장 과정에서 발생한 실패를 구분해 기록합니다.
    • 장시간 처리되지 않은 OAuth 요청을 자동으로 실패 처리해 재시도 및 복구가 쉬워졌습니다.
    • OAuth 인증 요청의 성공·실패 상태와 완료 시점을 안정적으로 추적합니다.
  • 테스트

    • 중복 요청 방지, 단계별 실패 기록, 오래된 요청 복구 및 오류 처리를 검증하는 테스트를 추가했습니다.

- OAuth 요청에 ISSUED, PROCESSING, SUCCEEDED, FAILED 상태 추가
- callback 처리 선점과 중복 요청 방지 로직 구현
- 성공 및 단계별 실패 상태와 오류 분류 기록
- 장기 PROCESSING 요청 자동 실패 처리
- OAuth 상태 관리 DB 마이그레이션 추가
- 상태 전환, 부분 실패 및 동시 요청 테스트 추가
@ownue
ownue requested review from hyeonky0w0 and riveryunny August 12, 2026 13:17
@ownue ownue self-assigned this Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ownue, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 4 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f8c4286-d52d-4e2c-aa42-b2caa66fc506

📥 Commits

Reviewing files that changed from the base of the PR and between 7068231 and b2d53f9.

📒 Files selected for processing (10)
  • database/migrations/20260812_01_oauth_callback_status.sql
  • src/main/java/com/example/todayEng/domain/user/entity/OAuthAuthorizationRequest.java
  • src/main/java/com/example/todayEng/domain/user/entity/enums/OAuthAuthorizationRequestStatus.java
  • src/main/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepository.java
  • src/main/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthService.java
  • src/main/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestService.java
  • src/main/java/com/example/todayEng/domain/user/service/OAuthCallbackCompletionService.java
  • src/test/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepositoryTest.java
  • src/test/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthServiceTest.java
  • src/test/java/com/example/todayEng/domain/user/service/OAuthCallbackCompletionServiceTest.java
📝 Walkthrough

Walkthrough

OAuth 인가 요청에 ISSUED, PROCESSING, SUCCEEDED, FAILED 상태를 추가했습니다. 콜백 처리 선점, 성공·실패 기록, 실패 원인 분류, 장기 처리 요청 복구, 관련 테스트를 구현했습니다.

Changes

OAuth 콜백 상태 관리

Layer / File(s) Summary
상태 저장 계약
database/migrations/20260812_01_oauth_callback_status.sql, src/main/java/com/example/todayEng/domain/user/entity/...
인가 요청에 상태, 실패 단계·유형, 처리 시작·완료 시각을 추가했습니다. 기존 행을 백필하고 상태 인덱스를 생성했습니다.
처리 클레임과 상태 전이
src/main/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepository.java, src/main/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestService.java, src/test/java/com/example/todayEng/domain/user/{repository,service}/...
ISSUED 요청을 원자적으로 PROCESSING으로 전환합니다. 처리 클레임을 반환하고 성공·실패 상태를 기록합니다. 동시 처리와 만료 후 성공 처리를 테스트했습니다.
콜백 처리와 정체 요청 복구
src/main/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthService.java, src/main/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestRecoveryScheduler.java, src/test/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthServiceTest.java
콜백 검증, 토큰 교환, 사용자 정보 조회, 계정 저장 단계를 추적합니다. 예외를 실패 유형으로 분류하고 원래 예외를 재전파합니다. 15분 이상 처리 중인 요청을 FAILED로 변경합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OAuthCallback as ExternalAccountOAuthService
  participant RequestService as OAuthAuthorizationRequestService
  participant RequestRepository as OAuthAuthorizationRequestRepository
  participant ProviderClient as OAuth provider client

  OAuthCallback->>RequestService: startProcessing(rawState, provider)
  RequestService->>RequestRepository: ISSUED -> PROCESSING
  RequestRepository-->>RequestService: ProcessingClaim
  OAuthCallback->>ProviderClient: 토큰 교환 및 사용자 정보 조회
  ProviderClient-->>OAuthCallback: 토큰 및 사용자 정보
  OAuthCallback->>RequestService: succeed(requestId)
  RequestService->>RequestRepository: PROCESSING -> SUCCEEDED
Loading

Possibly related PRs

  • Today-Eng/TodayEng-BE#33: OAuth 인가 요청 엔티티와 서비스의 초기 단일 소비 흐름을 추가했습니다.
  • Today-Eng/TodayEng-BE#34: Spotify OAuth 콜백 흐름을 추가했으며, 이번 변경이 해당 흐름에 상태 처리를 연결합니다.

Poem

ISSUED가 길을 열고,
PROCESSING이 잠시 멈춰 서네.
성공은 SUCCEEDED, 실패는 기록되어,
오래된 요청은 조용히 잠들고,
OAuth 상태는 질서 있게 흐르네.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive [35] 상태 전이, 실패 기록, stale 처리, 동시성 테스트는 구현되었지만 신규 OAuth 인가 URL 복구는 변경 요약에서 확인할 수 없습니다. 실패 후 기존 authorization code를 재사용하지 않고 신규 OAuth 인가 URL을 발급하는 흐름과 관련 테스트를 명시적으로 확인하거나 추가하세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 OAuth callback 처리 상태 관리라는 PR의 주요 변경 사항을 명확하고 간결하게 설명합니다.
Out of Scope Changes check ✅ Passed 마이그레이션, 엔티티, 저장소, 서비스, 스케줄러와 테스트 변경은 모두 [35]의 OAuth callback 상태 관리 범위에 포함됩니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#35-oauth-callback

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@database/migrations/20260812_01_oauth_callback_status.sql`:
- Around line 8-12: Update the migration’s status backfill so used_at alone
never assigns SUCCEEDED; preserve ISSUED for unused records and assign legacy
records without independent success evidence to the project’s LEGACY or UNKNOWN
status. Keep used_at-based reuse prevention intact, and document the transition
according to RFC 6749 sections 4.1.2–4.1.3 and the project audit policy.

In
`@src/main/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepository.java`:
- Around line 71-85: Update the stale-condition comparison in
failStaleProcessing to use <= so requests with processingStartedAt exactly equal
to staleBefore are marked failed. Add a boundary test covering
processingStartedAt == staleBefore and verify the request is updated.

In
`@src/main/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthService.java`:
- Around line 75-79: Bind externalAccountConnectionService.saveOrUpdate and
oauthAuthorizationRequestService.succeed into one completion transaction that
locks the request row and prevents the recovery scheduler from changing
PROCESSING during either operation. Update the relevant service transaction
boundaries while preserving OAuthCallbackFailureStage.ACCOUNT_SAVE handling, and
add an integration test covering scheduler execution between account persistence
and success completion.

In
`@src/test/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepositoryTest.java`:
- Around line 23-40: Update onlyOneCallbackCanAtomicallyStartProcessing to run
two callbacks concurrently using separate transactions and CountDownLatch
synchronization, following Spring TestContext transaction-testing conventions.
Have both attempts target the same issued request, assert that exactly one
result succeeds, and verify the final status is PROCESSING.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ce4566f-ccd5-41e4-9660-9b97f7c5024c

📥 Commits

Reviewing files that changed from the base of the PR and between 8e950a6 and 7068231.

📒 Files selected for processing (12)
  • database/migrations/20260812_01_oauth_callback_status.sql
  • src/main/java/com/example/todayEng/domain/user/entity/OAuthAuthorizationRequest.java
  • src/main/java/com/example/todayEng/domain/user/entity/enums/OAuthAuthorizationRequestStatus.java
  • src/main/java/com/example/todayEng/domain/user/entity/enums/OAuthCallbackFailureStage.java
  • src/main/java/com/example/todayEng/domain/user/entity/enums/OAuthCallbackFailureType.java
  • src/main/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepository.java
  • src/main/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthService.java
  • src/main/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestRecoveryScheduler.java
  • src/main/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestService.java
  • src/test/java/com/example/todayEng/domain/user/repository/OAuthAuthorizationRequestRepositoryTest.java
  • src/test/java/com/example/todayEng/domain/user/service/ExternalAccountOAuthServiceTest.java
  • src/test/java/com/example/todayEng/domain/user/service/OAuthAuthorizationRequestServiceTest.java

Comment thread database/migrations/20260812_01_oauth_callback_status.sql
- 기존 OAuth 요청을 LEGACY 상태로 안전하게 백필
- 15분 경과 요청을 포함하도록 stale 조건 수정
- 계정 저장과 성공 상태 전환을 단일 트랜잭션으로 처리
- 완료 처리와 recovery scheduler 간 경쟁 조건 방지
- 실제 동시 callback 및 상태 전환 경계 테스트 추가
@ownue
ownue merged commit a9bddfa into develop Aug 12, 2026
2 checks passed
@ownue
ownue deleted the feat/#35-oauth-callback branch August 13, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [FEAT] OAuth callback 처리 상태 관리

1 participant